package com.xiaoming.backend.service.impl;

import com.xiaoming.backend.dao.*;
import com.xiaoming.backend.dao.mapper.ExceptionInfoPOMapper;
import com.xiaoming.backend.dao.mapper.FacilityPOMapper;
import com.xiaoming.backend.dto.request.FindOrderRequest;
import com.xiaoming.backend.dto.request.UptOrderRequest;
import com.xiaoming.backend.dto.request.WasteRegistrationRequest;
import com.xiaoming.backend.dto.response.ExceptionInfoResponse;
import com.xiaoming.backend.dto.response.OrderResponse;
import com.xiaoming.backend.dto.response.TaskCountResponse;
import com.xiaoming.backend.entity.db.example.ExceptionInfoPOExample;
import com.xiaoming.backend.entity.db.po.CarTaskPO;
import com.xiaoming.backend.entity.db.po.ExceptionInfoPO;
import com.xiaoming.backend.entity.db.po.OrderPO;
import com.xiaoming.backend.entity.db.po.WastePO;
import com.xiaoming.backend.entity.orm.Order;
import com.xiaoming.backend.entity.orm.User;
import com.xiaoming.backend.result.exception.AppErrorException;
import com.xiaoming.backend.result.exception.error.AppError;
import com.xiaoming.backend.service.IWasteService;
import com.xiaoming.backend.util.DeepCopyUtil;
import com.xiaoming.backend.util.EntityUtil;
import com.xiaoming.backend.util.StringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class WasteServiceImpl implements IWasteService {
    private final  IWasteCategoryDao iWasteCategoryDao;

    private final  IOrderDao orderDao;

    private final  IWasteDao wasteDao;

    private final  ICarTaskDao carTaskDao;

    private final FacilityPOMapper facilityPOMapper;

    private final ExceptionInfoPOMapper exceptionInfoPOMapper;

    @Override
    @Transactional
    public void registerWaste(User user, WasteRegistrationRequest wasteRegistrationRequest) {

        // 验证权限
        if (!StringUtil.equals(User.MEDICAL, user.getRole()) && !StringUtil.equals(User.ADMIN, user.getRole())) {
            throw new AppErrorException(AppError.WASTE_ERROR);
        }

        // 验证废物类型
        Long disposalMethod = iWasteCategoryDao.getDisposalMethod(wasteRegistrationRequest.getWasteType());

        // 构建废物
        String facilityName = facilityPOMapper.selectByPrimaryKey(user.getFacilityId()).getFacilityName();
        Order order = Order.builder()
                .orderSqno(EntityUtil.getOrderSqnoStr())
                .orderWasteType(wasteRegistrationRequest.getWasteType())
                .orderStartFacilityId(user.getFacilityId())
                .orderStartFacilityName(facilityName)
                .orderStatus(wasteRegistrationRequest.getStatus())
                .wasteWeight(wasteRegistrationRequest.getWasteWeight())
                .crtdUserId(user.getUserId())
                .crtdDate(new Date())
                .crtdRemark(wasteRegistrationRequest.getRemark())
                .build();

        // 构建废物记录
        WastePO wastePO = EntityUtil.order2WastePO(order);
        wastePO.setDisposalMethod(disposalMethod);
        wasteDao.insertWaste(wastePO);
        order.setOrderWasteId(wastePO.getWasteId());

        //构建处理订单
        OrderPO orderPO = EntityUtil.order2OrderPO(order);
        // 保存处理订单
        int orderFlag = orderDao.insertOrder(orderPO);
        if (orderFlag != 1){
            throw new AppErrorException(AppError.ORDER_INERT_ERROR);
        }
        order.setOrderId(orderDao.getOrderId(orderPO));

        // 生成运输任务
        CarTaskPO carTaskPO = EntityUtil.order2CarTaskPO(order);
        int carTaskFlag = carTaskDao.insertCarTask(carTaskPO);
        if (carTaskFlag != 1){
            throw new AppErrorException(AppError.TASK_INERT_ERROR);
        }

    }

    @Override
    public List<OrderResponse> findOrder(FindOrderRequest findOrderRequest) {
        List<Order> orders = orderDao.getOrderInfo(findOrderRequest.getDisposqlUserId(), findOrderRequest.getCrtdUserId(),
                findOrderRequest.getStatus(), findOrderRequest.getStartFacilityId(), findOrderRequest.getEndFacilityId(),
                findOrderRequest.getDisposqlStartDate(), findOrderRequest.getDisposqlEndDate(),
                findOrderRequest.getCrtdStartDate(), findOrderRequest.getCrtdEndDate());
        if (orders.isEmpty()){
            return new ArrayList<>();
        }
        return orders.stream()
                .map(order -> DeepCopyUtil.copyByJackson(order, OrderResponse.class))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public int uptOrder(User user, UptOrderRequest uptOrderRequest) {

        if (User.MEDICAL.equals(user.getRole())) {
            orderDao.uptWaste(Integer.valueOf(uptOrderRequest.getOrderid()), uptOrderRequest.getOrderStatus(),
                    user.getUserId(), uptOrderRequest.getDisposqlRemark(),
                    uptOrderRequest.getDisposqlProgress(), null, null, Long.valueOf(uptOrderRequest.getWasteType()),
                    Long.valueOf(uptOrderRequest.getDisposalMethod()));
        }else {
            orderDao.uptWaste(Integer.valueOf(uptOrderRequest.getOrderid()), uptOrderRequest.getOrderStatus(),
                    user.getUserId(), uptOrderRequest.getDisposqlRemark(),
                    uptOrderRequest.getDisposqlProgress(),null, null, Long.valueOf(uptOrderRequest.getWasteType()),
                    Long.valueOf(uptOrderRequest.getDisposalMethod()));
        }
        return 0;
    }

    @Override
    public TaskCountResponse getTaskCount(User user) {
        TaskCountResponse countResponse = new TaskCountResponse();
        String todayTaskCount = "0";

        String allTaskCount = "0";

        countResponse.setErrCount("0");
        countResponse.setExceptionInfoResponses(new ArrayList<>());
        if (User.MEDICAL.equals(user.getRole())){
            todayTaskCount = orderDao.getMedicalOrderCount(user.getUserId(), new Date());

            allTaskCount = orderDao.getMedicalOrderCount(user.getUserId());
        }

        if (User.HANDLE.equals(user.getRole())){
            todayTaskCount = orderDao.getHandleOrderCount(user.getUserId(), new Date());

            allTaskCount = orderDao.getHandleOrderCount(user.getUserId());
        }

        if (User.TRANSPORT.equals(user.getRole())){
            todayTaskCount = carTaskDao.getTaskCount(user.getUserId(), new Date());

            allTaskCount = carTaskDao.getTaskCount(user.getUserId());
        }

        if (User.ADMIN.equals(user.getRole())){
            Long todayOrdersCount1 = orderDao.getOrderAdminCount(user.getFacilityId(), new Date());

            todayTaskCount = String.valueOf(todayOrdersCount1);

            Long allOrdersCount2 = orderDao.getOrderAdminCount(user.getUserId());

            allTaskCount = String.valueOf(allOrdersCount2);

            ExceptionInfoPOExample e = new ExceptionInfoPOExample();
            e.createCriteria().andUserIdEqualTo(user.getUserId());
            List<ExceptionInfoPO> exceptionInfoPOS = exceptionInfoPOMapper.selectByExample(e);
            if (!exceptionInfoPOS.isEmpty()) {
                List<ExceptionInfoResponse> responses = exceptionInfoPOS.stream()
                        .map(po -> DeepCopyUtil.copyByJackson(po, ExceptionInfoResponse.class))
                        .toList();
                countResponse.setErrCount(String.valueOf(responses.size()));
                countResponse.setExceptionInfoResponses(responses);
            }
        }

        countResponse.setTodayTaskCount(todayTaskCount);
        countResponse.setAllTaskCount(allTaskCount);

        return countResponse;
    }
}

